xen: Implement xen/alternative-call.h for use in common code
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 10 Sep 2021 20:12:56 +0000 (16:12 -0400)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 10 Sep 2021 19:30:26 +0000 (20:30 +0100)
The alternative call infrastructure is x86-only for now, but the common iommu
code has a variant and more common code wants to use the infrastructure.

Introduce CONFIG_ALTERNATIVE_CALL and a conditional implementation so common
code can use the optimisation when available, without requiring all
architectures to implement no-op stubs.

Write some documentation, which was thus far entirely absent, covering the
requirements for an architecture to implement this optimisation, and how to
use the infrastructure in general code.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/Kconfig
xen/common/Kconfig
xen/include/xen/alternative-call.h [new file with mode: 0644]

index 9b164db641871db202fe1aeff9c3106f3761b5e9..1f83518ee00f2e59fa967133c603016145cd6a22 100644 (file)
@@ -6,6 +6,7 @@ config X86
        def_bool y
        select ACPI
        select ACPI_LEGACY_TABLES_LOOKUP
+       select ALTERNATIVE_CALL
        select ARCH_SUPPORTS_INT128
        select CORE_PARKING
        select HAS_ALTERNATIVE
index 0ddd18e11af3c877333d59ed992db8614f4a7fce..ac5491b1cce72c31b72297daa7e007c0937ec131 100644 (file)
@@ -22,6 +22,9 @@ config GRANT_TABLE
 
          If unsure, say Y.
 
+config ALTERNATIVE_CALL
+       bool
+
 config HAS_ALTERNATIVE
        bool
 
diff --git a/xen/include/xen/alternative-call.h b/xen/include/xen/alternative-call.h
new file mode 100644 (file)
index 0000000..c2d3b70
--- /dev/null
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef XEN_ALTERNATIVE_CALL
+#define XEN_ALTERNATIVE_CALL
+
+/*
+ * Some subsystems in Xen may have multiple implementations, which can be
+ * resolved to a single implementation at boot time.  By default, this will
+ * result in the use of function pointers.
+ *
+ * Some architectures may have mechanisms for dynamically modifying .text.
+ * Using this mechanism, function pointers can be converted to direct calls
+ * which are typically more efficient at runtime.
+ *
+ * For architectures to support:
+ *
+ * - Implement alternative_{,v}call() in asm/alternative.h.  Code generation
+ *   requirements are to emit a function pointer call at build time, and stash
+ *   enough metadata to simplify the call at boot once the implementation has
+ *   been resolved.
+ * - Select ALTERNATIVE_CALL in Kconfig.
+ *
+ * To use:
+ *
+ * Consider the following simplified example.
+ *
+ *  1) struct foo_ops __alt_call_maybe_initdata ops;
+ *
+ *  2) const struct foo_ops __initconstrel foo_a_ops = { ... };
+ *     const struct foo_ops __initconstrel foo_b_ops = { ... };
+ *
+ *     void __init foo_init(void)
+ *     {
+ *         ...
+ *         if ( use_impl_a )
+ *             ops = *foo_a_ops;
+ *         else if ( use_impl_b )
+ *             ops = *foo_b_ops;
+ *         ...
+ *     }
+ *
+ *  3) alternative_call(ops.bar, ...);
+ *
+ * There needs to a single ops object (1) which will eventually contain the
+ * function pointers.  This should be populated in foo's init() function (2)
+ * by one of the available implementations.  To call functions, use
+ * alternative_{,v}call() referencing the main ops object (3).
+ */
+
+#ifdef CONFIG_ALTERNATIVE_CALL
+
+#include <asm/alternative.h>
+
+#define __alt_call_maybe_initdata __initdata
+
+#else
+
+#define alternative_call(func, args...)  (func)(args)
+#define alternative_vcall(func, args...) (func)(args)
+
+#define __alt_call_maybe_initdata __read_mostly
+
+#endif /* !CONFIG_ALTERNATIVE_CALL */
+#endif /* XEN_ALTERNATIVE_CALL */